package it.polimi.traveldream;

import it.polimi.traveldream.entities.Custompackage;
import it.polimi.traveldream.entities.Excursion;
import it.polimi.traveldream.entities.Hotel;
import it.polimi.traveldream.entities.PackageBase;
import it.polimi.traveldream.entities.Transport;
import it.polimi.traveldream.entities.User;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


/**
 * Session Bean implementation class GestioneRicerca
 */
@Stateless
public class GestioneRicerca implements GestioneRicercaLocal {
	
	@PersistenceContext
	private EntityManager em;
	
	@Resource
	private EJBContext context;
	
	public GestioneRicerca() {  }
	
    
    // ---------------------  METODI PER LA RICERCA DEI PACCHETTI ------------------------------------
	
	@Override
	public ArrayList<PackageDTO> ricercaPacchetto(String nome, String prezzomin, String prezzomax, String citta,Date data1,Date data2) {
		
		System.out.println(nome+"1");
		System.out.println(prezzomax+"ciao");
		System.out.println("prezzo max :"+prezzomax);
		System.out.println("prezzo min :"+prezzomin);
		int premin;
		if(!prezzomin.equals(""))premin=Integer.parseInt(prezzomin); else premin=0;
		int premax;
		if(!prezzomax.equals(""))premax=Integer.parseInt(prezzomax); else premax=0;
		System.out.println("prezzo max :"+premax);
		System.out.println("prezzo min :"+premin);
			
		  return convertToPackageDTO( serchPacchetto(nome,premin,premax,citta,data1,data2) );
	  }
	
	@Override
	public PackageDTO ricercaPacchettoById(int id){
		System.out.print("inizio ricerca pacchetto");
		return convertToPackageDTO((serchPacchettoById(id)));
	}
	
	@Override
	public ArrayList<CustompackageDTO> ricercaCustomPackages() {
		
		return convertToCustomPackageDTO(searchCustomPackageByUser(em.find(User.class, context.getCallerPrincipal().getName() ) ));
	}
	
	@Override
	public CustompackageDTO ricercaCustomPacchettoById(int parseInt) {
		
		return convertToCustomPackageDTO((searchCustomPackageById(parseInt))).get(0);
	}
	  
	
	@Override
	public TransportDTO ricercaVoloDTOById(int voloandata) {
		return convertToTransportDTO(em.find(Transport.class, voloandata));
	}
	
	@Override
	public ArrayList<PackageDTO> ricercaOfferte() {
		return convertToPackageDTO(searcOfferte());
	}
	
   	


	private TransportDTO convertToTransportDTO(Transport find) {
		TransportDTO tmp=new TransportDTO();
		
		tmp.setNome(find.getNome());
		tmp.setCittaPartenza(find.getCittaPartenza());
		tmp.setDataPartenza(find.getDataPartenza());
		tmp.setCittaArrivo(find.getCittaArrivo());
		tmp.setPrezzo(find.getPrezzo());
	
		return tmp;
	}


	public Hotel ricercaHotelById(int id){
    	 System.out.print("ingresso ricerca");
		return em.find(Hotel.class, id);
		
	}
	
	@Override
	public HotelDTO ricercaHotelDTOById(int id){
		return hotelDTO(ricercaHotelById(id));
	}
	
	
	
	// ----------------------------- METODI DI CONVERSIONE ---------------------------------------
	
	
	
	

	public ArrayList<CustompackageDTO> convertToCustomPackageDTO(List<Custompackage> srcCusPck) {
		 ArrayList<CustompackageDTO> tmp=new ArrayList<CustompackageDTO>();
		 
		 for(Custompackage ck:srcCusPck){
			 tmp.add(convertCustomDTO(ck));
		 }
		
		return tmp;
	}

	
	

	public CustompackageDTO convertCustomDTO(Custompackage ck) {
		CustompackageDTO temp=new CustompackageDTO();
		ArrayList<String>tmp=new ArrayList<String>();
		
		temp.setId(ck.getId());
		temp.setNome(ck.getNome());
		temp.setDescrizione(ck.getDescrizione());
		temp.setPrezzo(ck.getPrezzo());
		temp.setCitta(ck.getCitta());
		temp.setHotel(ck.getHotel().getId());
		temp.setVoloandata(ck.getAndata().getId());
		temp.setVoloritorno(ck.getRitorno().getId());
		for(Excursion ex:ck.getExcursions()){
			Integer i=ex.getId();
			tmp.add(i.toString());
		}
				
		return temp;
	}


	public PackageDTO convertToPackageDTO(PackageBase result){
		System.out.print("convertToPackageDTO single package");
		return convertDTO(result);
	}
  
	public ArrayList<PackageDTO> convertToPackageDTO(List<PackageBase> resultlist2) {
		
    	ArrayList<PackageDTO> tmp=new ArrayList<PackageDTO>(); //  ricerca by ID
    	  
      for(PackageBase in :resultlist2){
    		tmp.add(convertDTO(in));
    	}
    	
       	System.out.print("fine convertToPackageDTO");
    	
		return tmp;
	}


	public PackageDTO convertDTO(PackageBase next) {
		
		System.out.print("inizio convertDTO");
		System.out.print(" nome pacchetto "+next.getNome());
		PackageDTO pk=new PackageDTO();
		
		pk.setId(next.getId());
		pk.setNome(next.getNome());
		pk.setDescrizione(next.getDescrizione());
		pk.setCitta(next.getCitta());
		pk.setPrezzo(next.getPrezzo());
		pk.setDurataviaggio(next.getDurataviaggio());
		pk.setHotel( hotelToHotelDTO(next.getHotels())   );
		pk.setVoliandata(transportToTransportDTO(next.getTransports()));
		pk.setVoliritorno(transportToTransportDTO(next.getTransportsritorno()));
		pk.setEscursioni(excursionToExcursionDTO(next.getExcursions()));
		
		
		System.out.print("fine convertDTO");
		
		return pk;
	}

	public ArrayList<ExcursionDTO> excursionToExcursionDTO(List<Excursion> excursions) {
		
		ArrayList<ExcursionDTO>tmp=new ArrayList<ExcursionDTO>();
		for(Excursion in :excursions){
			
			ExcursionDTO pk=new ExcursionDTO();
			pk.setId(in.getId());
			pk.setName(in.getName());;
		    pk.setDurata(in.getDurata());
		    pk.setDescription(in.getDescription());
		    pk.setPrice(in.getPrice());
			
			tmp.add(pk);
	      }
		
		return tmp;
	}



	private HotelDTO hotelDTO(Hotel in){
		HotelDTO pk=new HotelDTO();
		pk.setId(in.getId());
		pk.setName(in.getName());;
		pk.setIndirizzo(in.getIndirizzo());
		pk.setDescription(in.getDescription());
		pk.setPrice(in.getPrice());
		pk.setStelle(in.getStelle());
		return pk;
	}
	
	private ArrayList<HotelDTO> hotelToHotelDTO(List<Hotel> hotels) {
		
		ArrayList<HotelDTO>tmp=new ArrayList<HotelDTO>();
		for(Hotel in :hotels){
			
			HotelDTO pk=new HotelDTO();
			pk.setId(in.getId());
			pk.setName(in.getName());;
			pk.setIndirizzo(in.getIndirizzo());
			pk.setDescription(in.getDescription());
			pk.setPrice(in.getPrice());
			pk.setStelle(in.getStelle());
			
			tmp.add(pk);
	      }
		
		return tmp;
	}
	
	public ArrayList<TransportDTO> transportToTransportDTO(List<Transport> voli){
		ArrayList<TransportDTO>tmp=new ArrayList<TransportDTO>();
		for(Transport in :voli){
			
			TransportDTO pk=new TransportDTO();
			pk.setId(in.getId());
			pk.setNome(in.getNome());
			pk.setPrezzo(in.getPrezzo());
			pk.setFrequenza(in.getFrequenza());
			pk.setNPosti(in.getNPosti());
			pk.setCittaPartenza(in.getCittaPartenza());
			pk.setCittaArrivo(in.getCittaArrivo());
			pk.setDataPartenza(in.getDataPartenza());
			
			tmp.add(pk);
	      }
		
		return tmp;
		
	}
	

	//----------------------------------------  QUERY DI RICERCA ----------------------------
	



	private List<PackageBase> serchPacchetto(String nome, int min, int max, String citta,Date data1,Date data2) {
    
				String query="SELECT s " +
	    	    "FROM PackageBase s  " +
	    		"WHERE (s.disponibile=1) AND ";
		if(data1!=null) query+="exists(select f from s.transportsandata f where f.dataPartenza >= (:data1)) AND ";
		if(data2!=null) query+="exists(select f from s.transportsritorno f where f.dataPartenza < (:data2)) AND ";
		if(!nome.isEmpty())query+="(s.nome LIKE (:similarname)) AND ";
		if(max!=0) query+="(s.prezzo<(:max)) AND ";
		if(min!=0) query+="(s.prezzo>(:min)) AND ";
		if(!citta.isEmpty())query+="(s.citta LIKE (:similarcitta)) AND";
		query=query.substring(0,query.length()-4); 
	 	  
        query+="ORDER BY s.prezzo";
        System.out.print(query);
    	
    	Query q=em.createQuery(query,PackageBase.class);
    	
    	if(data1!=null)q.setParameter("data1",data1);
    	if(data2!=null)q.setParameter("data2",data2);
    	if(!nome.isEmpty()) q.setParameter("similarname","%" + nome + "%");
    	
    	if(max!=0) q.setParameter("max", max);
    	if(min!=0) q.setParameter("min", min);
    	if(!citta.isEmpty()) q.setParameter("similarcitta","%" + citta + "%");
    	
        return q.getResultList();
	}
    
    
	 /* private List<PackageBase> serchPacchettoById(int id) {
			
		   System.out.print("ricerca by id");
			String query="SELECT s " +
		    	    "FROM PackageBase s " +
		    		"WHERE (s.id=(:id)) ";
			    	
	    	Query q=em.createQuery(query,PackageBase.class);
	        
	    	q.setParameter("id", id);
	    	    	
	        return  (q.getResultList());
		}*/
	
	private PackageBase serchPacchettoById(int id){
		PackageBase tmp= em.find(PackageBase.class,id);
		int i=1;
		if(tmp.getDisponibile()==i) return tmp;
		return null;
		
			}
		

	  private List<Custompackage> searchCustomPackageByUser(User user) {
			
			String query="SELECT s " +
		    	    "FROM Custompackage s " +
		    		"WHERE "+
		    	    "(s.user = (:similarname))";
			
			
			Query q=em.createQuery(query,Custompackage.class);
			q.setParameter("similarname", user);
			
			return (q.getResultList());
		
		}
     
	  private List<Custompackage> searchCustomPackageById(int parseInt) {
			
		  System.out.print("ricerca by id");
			String query="SELECT s " +
		    	    "FROM Custompackage s " +
		    		"WHERE (s.id=(:id))";
			    	
	    	Query q=em.createQuery(query,PackageBase.class);
	        
	    	q.setParameter("id", parseInt);
	    	    	
	        return  (q.getResultList());
		}
	  
	private List<Hotel> serchHotel(int id) {
		String query="SELECT s " +
	    	    "FROM PackageBase s " +
	    		"WHERE "+
	    	    "(s.nome LIKE (:similarname)) AND (s.disponibile=1) ";
		
		Query q=em.createQuery(query,PackageBase.class);
		
		return (q.getResultList());
	}
	
	private List<PackageBase> searcOfferte() {
	
		String query="SELECT s FROM PackageBase s WHERE (s.inOfferta=1) AND (s.disponibile=1)";
		
		Query q=em.createQuery(query,PackageBase.class);
		
		
		return (q.getResultList());
	
	}





	


	
	
}
